package com.pub.stripe.service.impl;

import com.pub.stripe.model.CreateOrderEntity;
import com.pub.stripe.model.CreateRefundEntity;
import com.pub.stripe.service.OrderService;
import com.stripe.Stripe;
import com.stripe.model.Price;
import com.stripe.model.Product;
import com.stripe.model.Refund;
import com.stripe.model.checkout.Session;
import com.stripe.param.RefundCreateParams;
import com.stripe.param.checkout.SessionCreateParams;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.jetty.util.StringUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import spark.utils.StringUtils;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Service
public class OrderServiceImpl implements OrderService {

    @Value("${stripe.apiKey}")
    private String apiKey;

    @Value("${stripe.cancelUrl}")
    private String cancelUrl;

    @Value("${stripe.successUrl}")
    private String successUrl;
    @Override
    public String pay(CreateOrderEntity createOrderEntity) {
        Stripe.apiKey = apiKey;
        try {
            //创建产品
            Map<String, Object> params = new HashMap<>();
            params.put("name", createOrderEntity.getProductName());
            Product product = Product.create(params);

            //创建价格
            Map<String, Object> priceParams = new HashMap<>();
            BigDecimal actualAmount = createOrderEntity.getAmount().multiply(BigDecimal.valueOf(100));  //stripe的默认单位是分，即传入的amount实际上小数点会被左移两位
            //给price绑定元数据并更新price用于检索
            Map<String, Object> metadata = new HashMap<>();
            metadata.put("orderId", createOrderEntity.getOrderId());
            priceParams.put("metadata", metadata);  //通过订单号关联用于检索price信息（可选）
            priceParams.put("unit_amount", actualAmount.intValue());
            priceParams.put("currency", createOrderEntity.getCurrency());
            priceParams.put("product", product.getId());
            Price price = Price.create(priceParams);

            //创建支付信息得到url
            SessionCreateParams params3 = SessionCreateParams.builder()
                    .setMode(SessionCreateParams.Mode.PAYMENT)
                    .setSuccessUrl(successUrl)  //可自定义成功页面
                    .setCancelUrl(cancelUrl)
                    .addLineItem(
                            SessionCreateParams.LineItem.builder()
                                    .setQuantity(createOrderEntity.getQuantity())
                                    .setPrice(price.getId())
                                    .build()).putMetadata("orderId",createOrderEntity.getOrderId())  //通过订单号关联用于检索支付信息（可选）
                    .build();
            Session session = Session.create(params3);
            System.out.println("sessionId:" +session.getId());
            String sessionId = session.getId();  //退款方式1：拿到sessionId入库，退款的时候根据这个id找到PaymentIntent的id然后发起退款
            return session.getUrl();
        }catch (Exception e){
            log.error("创建支付会话出现异常：",e);
        }
        return "";
    }

    @Override
    public void refund(CreateRefundEntity createRefund) {
        try{
            Stripe.apiKey = apiKey;

            if (StringUtils.isNotEmpty(createRefund.getSessionId())){  //根据会话编号退款
                Session session =
                        Session.retrieve(
                                createRefund.getSessionId()
                        );
                RefundCreateParams params;
                if (createRefund.getAmount() != null && createRefund.getAmount().compareTo(BigDecimal.ZERO) != 0){  //指定退款金额
                    BigDecimal actualAmount = createRefund.getAmount().multiply(BigDecimal.valueOf(100));  //api默认单位分
                    params = RefundCreateParams.builder()
                            .setPaymentIntent(session.getPaymentIntent())
                            .setAmount(actualAmount.longValue())
                            .build();
                }else {  //全额退款
                    params = RefundCreateParams.builder()
                            .setPaymentIntent(session.getPaymentIntent())
                            .build();
                }
                Refund.create(params);
                log.info("根据会话编号退款成功");
                return;
            }
            if (StringUtils.isNotEmpty(createRefund.getChargeId())){  //根据退款编号退款
                Map<String, Object> params = new HashMap<>();
                params.put("charge", createRefund.getChargeId());
                if (createRefund.getAmount() != null && createRefund.getAmount().compareTo(BigDecimal.ZERO) != 0){  //指定退款金额，否则全额退款
                    BigDecimal actualAmount = createRefund.getAmount().multiply(BigDecimal.valueOf(100));  //api默认单位分
                    params.put("amount", actualAmount.longValue());
                }
                Refund.create(params);
                log.info("根据退款编号退款成功");
                return;
            }
        }catch (Exception e){
            //e.getMessage.contain("charge_already_refunded") 已退款
            //e.getMessage.contain("resource_missing") 退款编号错误
            //e.getMessage.contain("amount on charge ($n)") 金额应小于n
            log.error("退款异常：",e);
        }
    }
}
